﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Windows;
using System.Globalization;
using System.ComponentModel;
using BrainTechLLC;
using System.Windows.Threading;
using BrainTechLLC.ThreadSafeObjects;
using System.Threading;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.Serialization;

namespace BrainTechLLC.WPF
{
    public class ViewModelValueConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            ViewModelBase vm = value as ViewModelBase;

            if (vm == null || parameter == null)
            {
                return value;
            }

            string propertyName = parameter.ToString();
            Type vmType = vm.GetType();
            object destValue = null;

            PropertyInfo propInfo = vmType.GetProperty(propertyName, BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public
                | BindingFlags.NonPublic);

            if (propInfo == null)
            {
                if (vm.Object == null)
                {
                    return value;
                }
                Type wrappedObjectType = vm.Object.GetType();
                propInfo = wrappedObjectType.GetProperty(propertyName, BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public
                    | BindingFlags.NonPublic);

                if (propInfo == null)
                {
                    throw new Exception(string.Format("Property {0} not found on type {1}", propertyName, vmType));
                }

                destValue = propInfo.GetValue(vm.Object, null);
            }
            else
            {
                destValue = propInfo.GetValue(vm, null);
            }

            return destValue;

        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            ViewModelBase vm = value as ViewModelBase;

            if (vm == null || parameter == null)
            {
                return value;
            }

            string propertyName = parameter.ToString();
            Type vmType = vm.GetType();
            object destValue = null;

            PropertyInfo propInfo = vmType.GetProperty(propertyName, BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public
                | BindingFlags.NonPublic);

            if (propInfo == null)
            {
                if (vm.Object == null)
                {
                    return value;
                }
                Type wrappedObjectType = vm.Object.GetType();
                propInfo = wrappedObjectType.GetProperty(propertyName, BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public
                    | BindingFlags.NonPublic);

                if (propInfo == null)
                {
                    throw new Exception(string.Format("Property {0} not found on type {1}", propertyName, vmType));
                }

                destValue = propInfo.GetValue(vm.Object, null);
            }
            else
            {
                destValue = propInfo.GetValue(vm, null);
            }

            return destValue;
        }
    }
}
